package services

import (
	"errors"
	"fmt"
	"hft/Database/admin"
	"hft/Http/Models/request"
	models "hft/Http/Models/request"
	"hft/Http/Services/base"
	utils "hft/Http/Utils"
	"hft/e"
	"hft/global"
	"hft/tools"

	"gorm.io/gorm"
)

type Role struct{}

func (r *Role) AddRole(role *admin.Role) error {

	var parentRole *admin.Role

	if role.PID == 0 {
		return errors.New("无效的父角色id")
	}

	err := global.OC_DB.Transaction(func(tx *gorm.DB) error {

		// 先查找父角色
		if err := tx.First(&parentRole, role.PID).Error; err != nil {
			return errors.New("父角色不存在")
		} else {
			// 如果存在就更新link
			role.Link = fmt.Sprintf("%v%v,", parentRole.Link, role.PID)
			// 开始查找当前的角色
			if res := tx.Where("id = ?", role.ID).Omit("id,deleted_at").FirstOrCreate(&role); res.Error != nil {
				return errors.New("未知错误500")
			} else if res.RowsAffected == 0 {
				return errors.New("角色已存在")
			} else {
				var root *admin.Route
				// 默认添加根目录
				if err := tx.First(&root, 1).Error; err != nil {
					return errors.New("添加超级权限失败")
				} else {
					tx.Model(&role).Association("Routes").Append(root)
					return nil
				}
			}
		}

	})

	return err
}

func (r *Role) EditRole(role *admin.Role) error {

	var searchRole *admin.Role

	err := global.OC_DB.Transaction(func(tx *gorm.DB) error {

		if err := tx.Where("id = ?", role.ID).First(&searchRole).Error; err != nil {
			return errors.New("该角色不存在")
		} else {
			tx.Model(&admin.Role{}).Where("id = ?", role.ID).Omit("p_id,create_time,deleted_at,role_value,can_be_set_region").Save(&role)
			return nil
		}

	})

	return err
}

func (r *Role) ChangeRoleRoute(res *models.ResIds) error {
	// 观察是否包含某个根目录
	var routesSlice = tools.AddIfNotExist(res.IDS, 1)
	var myRoutes []*admin.Route //一定一定要有切片来接
	var role *admin.Role
	// fmt.Println(routesSlice)

	err := global.OC_DB.Transaction(func(tx *gorm.DB) error {

		if err := tx.First(&role, res.RoleId).Error; err != nil {
			return errors.New("无该角色")
		} else {
			if err := tx.Find(&myRoutes, routesSlice).Error; err != nil {
				return errors.New("未知错误500")
			} else {
				tx.Model(&role).Association("Routes").Clear()
				tx.Model(&role).Association("Routes").Append(myRoutes)

				return nil
			}
		}
	})

	return err
}

func (r *Role) ChangeRoleApi(res *models.ResIds) error {
	// 观察是否包含某个根目录
	// var routesSlice = tools.AddIfNotExist(res.IDS, 1)
	var myApi []*admin.Api //一定一定要有切片来接
	var role *admin.Role
	// fmt.Println(routesSlice)

	err := global.OC_DB.Transaction(func(tx *gorm.DB) error {

		if err := tx.First(&role, res.RoleId).Error; err != nil {
			return errors.New("无该角色")
		} else {
			if err := tx.Find(&myApi, res.IDS).Error; err != nil {
				return errors.New("未知错误500")
			} else {
				tx.Model(&role).Association("Apis").Clear()
				tx.Model(&role).Association("Apis").Append(myApi)

				return nil
			}
		}
	})

	return err
}

func (r *Role) GetRoleList(claims tools.BaseClaims) (roles []*admin.Role, err error) {

	account, err := base.FindAccount(claims, global.OC_DB)

	if err != nil {
		return nil, err
	}

	var role *admin.Role

	err = global.OC_DB.First(&role, account.RoleId).Error

	if err != nil {
		return nil, errors.New(e.RoleNotExist)
	}

	var list = make([]*admin.Role, 0)

	global.OC_DB.Where("link LIKE ?", fmt.Sprintf("%v%%", role.Link)).Preload("Routes").Preload("Apis").Order("sort asc").Find(&list)

	var treeRole = make([]*admin.Role, 0)

	treeRole = append(treeRole, utils.BuildTree(list, role.ID))

	return treeRole, nil //不要修改自己的权限所以采用roles
}

// 添加权限
func (r *Role) ChangePower(power *request.Power) error {

	var role *admin.Role
	var MyApis []*admin.Api
	var MyRoutes []*admin.Route
	if power.RoleId == 0 {
		return errors.New("无效的角色")
	} else {
		err := global.OC_DB.Transaction(func(tx *gorm.DB) error {

			if err := tx.Where("id = ?", power.RoleId).First(&role).Error; err != nil {
				return errors.New("无该角色信息")
			} else {
				if len(power.Apis) == 0 {
					tx.Model(&role).Association("Apis").Clear()
				} else {
					if err := tx.Find(&MyApis, power.Apis).Error; err != nil {
						return errors.New("未知错误")
					} else {
						tx.Model(&role).Association("Apis").Clear()
						tx.Model(&role).Association("Apis").Append(MyApis)
					}
				}

				if len(power.Routes) == 0 {

					var root uint = 1

					power.Routes = append(power.Routes, &root)
				}

				if err := tx.Find(&MyRoutes, power.Routes).Error; err != nil {
					return errors.New("未知错误")
				} else {
					tx.Model(&role).Association("Routes").Clear()
					tx.Model(&role).Association("Routes").Append(MyRoutes)
				}
				return nil

			}

		})
		return err
	}

}

var RoleService = new(Role)
